package com.rongzhe.house.index;


import com.alibaba.fastjson.JSONObject;
import com.rongzhe.house.banner.entity.Banner;
import com.rongzhe.house.banner.enums.BannerType;
import com.rongzhe.house.banner.service.BannerService;
import com.rongzhe.house.common.constants.Constants;
import com.rongzhe.house.common.constants.QueryConstants;
import com.rongzhe.house.common.exception.RongZheBusinessException;
import com.rongzhe.house.common.resp.ApiResult;
import com.rongzhe.house.house.criteria.HouseCriteria;
import com.rongzhe.house.house.criteria.HouseMapCriteria;
import com.rongzhe.house.house.entity.HouseOverview;
import com.rongzhe.house.house.service.HouseService;
import com.rongzhe.house.login.entity.User;
import com.rongzhe.house.position.entity.HousePositionCounty;
import com.rongzhe.house.position.entity.HousePositionTown;
import com.rongzhe.house.position.entity.HouseRoute;
import com.rongzhe.house.position.entity.HouseRouteStation;
import com.rongzhe.house.position.service.PositionService;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class IndexController {
    public static final String ES_HOUSE_INDEX = "house";

    private static final String DEFAULT_PROVINCE = "5001";

    private static final String NONE = "-1";

    @Autowired
    private HouseService houseService;

    @Autowired
    private BannerService bannerService;

    @Autowired
    private PositionService positionService;

    @Autowired
    private Client client;

    /**
     * 关于我们
     * @return
     * @throws RongZheBusinessException
     */
    @RequestMapping(value = {"/newAbout"}, method = RequestMethod.GET)
    public String about() throws RongZheBusinessException {
        return "about";
    }
    /**
     * 生活服务
     * @param mode
     * @param houseCriteria
     * @return
     * @throws RongZheBusinessException
     */
    @RequestMapping(value = {"/newLife"}, method = RequestMethod.GET)
    public String life(Model mode,HouseCriteria houseCriteria) throws RongZheBusinessException {
        return "life";
    }

    /**
     * 房屋委托
     * @param mode
     * @param houseCriteria
     * @return
     * @throws RongZheBusinessException
     */
    @RequestMapping(value = {"/newEntrust"}, method = RequestMethod.GET)
    public String entrust(Model mode,HouseCriteria houseCriteria) throws RongZheBusinessException {
        return "entrust";
    }

    @RequestMapping(value = {"/map/list"}, method = RequestMethod.GET)
    @ResponseBody
    public JSONObject list(Model mode,HouseMapCriteria houseCriteria) throws RongZheBusinessException {
        houseCriteria.setFindRound(true);
        return houseService.map(houseCriteria);
    }
    @RequestMapping(value = {"/map"}, method = RequestMethod.GET)
    public String map(Model mode,HouseCriteria houseCriteria) throws RongZheBusinessException {
        return "map";
    }

    @RequestMapping(value = {"/map/suggest"}, method = RequestMethod.GET)
    @ResponseBody
    public JSONObject suggest(HouseMapCriteria houseCriteria) throws RongZheBusinessException {
        return houseService.map(houseCriteria);
    }
    @RequestMapping(value = {"/map/count"}, method = RequestMethod.GET)
    @ResponseBody
    public List<HouseMapCriteria> count(HttpServletRequest request,Model mode, HouseMapCriteria houseCriteria) throws RongZheBusinessException {
        return houseService.queryCityMapCount(houseCriteria);
    }


    @RequestMapping(value = {"/index", "/"}, method = RequestMethod.GET)
    public String index(Model mode, @RequestParam(value = "province", defaultValue = DEFAULT_PROVINCE) String province) throws RongZheBusinessException {
        ApiResult entireRentHouse = houseService.getExcellentHouse(province,true,false);//整租
        ApiResult notEntireRentHouse = houseService.getExcellentHouse(province,false,false);//合租
        ApiResult ownerRentHouse = houseService.getExcellentHouse(province,false,true);//直租

        mode.addAttribute("entireRentHouse",entireRentHouse.getData());
        mode.addAttribute("notEntireRentHouse",notEntireRentHouse.getData());
        mode.addAttribute("ownerRentHouse",ownerRentHouse.getData());

        //List<HouseOverview> houseOverviews = houseService.getExcellentHouse(province);
        //mode.addAttribute("houseOverviewList", houseOverviews);

        List<Banner> bannerList = bannerService.getBannerListByType(BannerType.INDEX, province);

        mode.addAttribute("bannerList", bannerList);


        mode.addAttribute("regionList", positionService.getCountyListByProvinceId(province));

        return "index";
    }


    @RequestMapping(value = {"/detail"}, method = RequestMethod.GET)
    public String detail(Model mode, @RequestParam("houseId") Integer houseId, @RequestParam(value = "type",defaultValue = "0") Integer type, HttpServletRequest request, HttpServletResponse response) throws RongZheBusinessException {

        mode.addAttribute("house", houseService.detail(houseId));

        mode.addAttribute("type",type);

        mode.addAttribute("ehouse",houseService.getExcellentHouse("5001"));

        User user = (User) request.getSession().getAttribute(Constants.USER_LOGIN_KEY);
        mode.addAttribute("scFlag",false);
        if(null!=user){
            boolean b = houseService.hasCollection(houseId, user.getId());
            mode.addAttribute("scFlag",b);
        }
        return "detail";
    }

    @RequestMapping(value = {"/index/search"},method = RequestMethod.GET)
    @ResponseBody
    public JSONObject queryList(Model mode, HttpServletRequest request){
        return doSearch(request);
    }

    @RequestMapping(value = {"/list"}, method = RequestMethod.GET)
    public String list(Model mode, HttpServletRequest request) throws RongZheBusinessException {
        //update by chengjia 2018年3月8日15:29:11
        JSONObject result = doSearch(request);
        mode.addAttribute("searchList", result);
        return "search";
    }

    /**
     * 搜索功能
     * 2018年3月8日15:28:37
     * @param request
     */
    private JSONObject doSearch(HttpServletRequest request){
        JSONObject result=new JSONObject();
        //区域
        List<HousePositionCounty> housePositionCounties = positionService.getCountyListByCityId(DEFAULT_PROVINCE);
        result.put("housePositionCounties",housePositionCounties);
        //地铁
        List<HouseRoute> houseRoutes = positionService.getRouteListByProvinceId(DEFAULT_PROVINCE);
        result.put("houseRoutes", houseRoutes);

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        String cityId=request.getParameter("cityId");
        boolQueryBuilder.must(QueryBuilders.termQuery("cityId", cityId==null?DEFAULT_PROVINCE:cityId));

        String type=request.getParameter("type");
        if(!StringUtils.isEmpty(type)){
            if("1".equals(type)){
                //boolQueryBuilder.must(QueryBuilders.termQuery("isOwnerRent", true));//荣者寓
            }else if("2".equals(type)){
                boolQueryBuilder.must(QueryBuilders.termQuery("isEntireRent", false));//荣者合租
            }else if("3".equals(type)){
                boolQueryBuilder.must(QueryBuilders.termQuery("isEntireRent", true));//荣者整租
            }else if("4".equals(type)){
                //荣者民宿
            }else if("5".equals(type)){
                //荣者驿
            }
        }
        if(null==type || "".equals(type) || "null".equals(type)){
            type="-1";
        }
        result.put("type",null==type?"":type);

        String keyword = request.getParameter("keyword");
        if (!StringUtils.isEmpty(keyword)) {
            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(keyword, "name", "countyName", "route", "station"));
        }
        result.put("keyword",null==keyword?"":keyword);

        String roomNum = request.getParameter("roomNum");
        if (StringUtils.isEmpty(roomNum)||NONE.equals(roomNum)) {
            roomNum = NONE;
        }else{
            boolQueryBuilder.must(QueryBuilders.termsQuery("roomNum", roomNum));
        }
        result.put("roomNum", roomNum);

        String countyId = request.getParameter("countyId");
        if (StringUtils.isEmpty(countyId)||NONE.equals(countyId)) {
            countyId = NONE;
        }else{
            boolQueryBuilder.must(QueryBuilders.termsQuery("countyId", countyId));
        }
        result.put("countyId", countyId);

        String townId = request.getParameter("townId");
        if (StringUtils.isEmpty(townId)||NONE.equals(townId)) {
            townId = NONE;
        }else{
            boolQueryBuilder.must(QueryBuilders.termsQuery("townId", townId));
        }
        result.put("townId", townId);

        String routeId = request.getParameter("routeId");
        if (StringUtils.isEmpty(routeId)||NONE.equals(routeId)) {
            routeId = NONE;
        }else{
            boolQueryBuilder.must(QueryBuilders.termsQuery("railList", routeId));
            //boolQueryBuilder.must(QueryBuilders.multiMatchQuery(routeId, "name", "countyName", "route", "station"));
        }
        result.put("routeId", routeId);

        String stationId = request.getParameter("stationId");
        if (StringUtils.isEmpty(stationId)||NONE.equals(stationId)) {
            stationId = NONE;
        }else{
            //boolQueryBuilder.must(QueryBuilders.termsQuery("stationId", stationId));
            //boolQueryBuilder.must(QueryBuilders.multiMatchQuery(stationId, "name", "countyName", "route", "station"));
        }
        result.put("stationId", stationId);

        String rent = request.getParameter("rent");
        if (StringUtils.isEmpty(rent)||NONE.equals(rent)) {
            rent = NONE;
            result.put("rent", rent);
        } else {
            result.put("rent", rent);
            List<BigDecimal> values = QueryConstants.RENT_VALUE.get(rent);
            BigDecimal rentStart=values.get(0);
            BigDecimal rentEnd=values.get(1);
            if (rentStart!= null && rentEnd!= null) {
                boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").gte(rentStart.doubleValue()).lte(rentEnd.doubleValue()));
            }

            if (rentStart!= null && rentEnd== null) {
                boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").gte(rentStart.doubleValue()));
            }

            if (rentStart== null && rentEnd!= null) {
                boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").lte(rentEnd.doubleValue()));
            }
        }

        String area = request.getParameter("area");
        if (StringUtils.isEmpty(area)||NONE.equals(area)) {
            area = NONE;
            result.put("area", area);
        } else {
            result.put("area", area);
            List<BigDecimal> values = QueryConstants.AREA_VALUE.get(area);
            BigDecimal areaStart=values.get(0);
            BigDecimal areaEnd=values.get(1);
            if (areaStart!= null && areaEnd!= null) {
                boolQueryBuilder.must(QueryBuilders.rangeQuery("area").gte(areaStart.doubleValue()).lte(areaEnd.doubleValue()));
            }
            if (areaStart!= null && areaEnd== null) {
                boolQueryBuilder.must(QueryBuilders.rangeQuery("area").gte(areaStart.doubleValue()));
            }
            if (areaStart== null && areaEnd!= null) {
                boolQueryBuilder.must(QueryBuilders.rangeQuery("area").lte(areaEnd.doubleValue()));
            }
        }

        String currentpageStr = request.getParameter("currentpage");
        int page=1;
        if(StringUtils.isBlank(currentpageStr)){
            page=1;
        }else{
            page=Integer.valueOf(currentpageStr);
        }
        result.put("currentpage",page);
        SearchRequestBuilder srb1 = client
                .prepareSearch(ES_HOUSE_INDEX).setQuery(boolQueryBuilder).setFrom((page-1)*10).setSize(10)
                .addSort("insertTime", SortOrder.DESC);

        MultiSearchResponse sr = client.prepareMultiSearch()
                .add(srb1)
                .get();
        List<Long> ids = new ArrayList<>();
        long total=0;
       for (MultiSearchResponse.Item item : sr.getResponses()) {

            SearchResponse response = item.getResponse();

            if (response == null) {
                continue;
            }
            SearchHit[] searchHits = response.getHits().getHits();
            if (searchHits != null && searchHits.length != 0) {
                total=(response.getHits().getTotalHits()%10==0?response.getHits().getTotalHits()/10:(response.getHits().getTotalHits()/10)+1);
                for (int i = 0; i < searchHits.length; i++) {
                    ids.add(Long.parseLong(searchHits[i].getId()));
                }
            }
        }

        //////

         /* for(int i=123;i<159;i++){
              ids.add(Long.valueOf(i));
          }*/
        //////

        result.put("total",total);
        result.put("houseOverviews", null);
        String orderStr = request.getParameter("orderStr");
        result.put("orderStr",orderStr==""?1:orderStr);
        if (!CollectionUtils.isEmpty(ids)) {
            if (StringUtils.isEmpty(orderStr)) {
                orderStr=QueryConstants.ORDER_STR.get("1");
            } else {
                orderStr = QueryConstants.ORDER_STR.get(orderStr);
                orderStr = orderStr == null ? QueryConstants.ORDER_STR.get("1") : orderStr;
            }

            String order = request.getParameter("order");
            if (StringUtils.isEmpty(order)) {
                order=QueryConstants.ORDER.get("1");
            } else {
                order = QueryConstants.ORDER.get(order);
                order = orderStr == null ? QueryConstants.ORDER.get("1") : order;
            }
            List<HouseOverview> houseOverviews = houseService.selectHouseByIds(ids,orderStr,order);
            result.put("houseOverviews", houseOverviews);
        }
        List<QueryTag> queryTags = new ArrayList<>();
        warpQueryTags(queryTags, housePositionCounties, houseRoutes, countyId, townId, routeId, stationId, roomNum, rent, area,keyword,type);
        result.put("queryTags", queryTags);
        return result;
    }

    private List<QueryTag> warpQueryTags(List<QueryTag> queryTags,
                                         List<HousePositionCounty> housePositionCounties,
                                         List<HouseRoute> houseRoutes,
                                         String countyId,
                                         String townId,
                                         String routeId,
                                         String stationId,
                                         String roomNum,
                                         String rent,
                                         String area,
                                         String keyword,
                                         String type) {


        String countyName;

        String townName;

        for (HousePositionCounty housePositionCounty : housePositionCounties) {
            if (housePositionCounty.getCountyId().toString().equals(countyId)) {

                countyName = housePositionCounty.getCountyName();
                QueryTag countyTag = new QueryTag();
                countyTag.setTagName(countyName);
                countyTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area, keyword,type,"countyId"));

                queryTags.add(countyTag);


                for (HousePositionTown housePositionTown : housePositionCounty.getTownList()) {
                    if (housePositionTown.getTownId().toString().equals(townId)) {
                        townName = housePositionTown.getTownName();
                        QueryTag townTag = new QueryTag();
                        townTag.setTagName(townName);
                        townTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area,keyword,type, "townId"));
                        queryTags.add(townTag);
                    }
                }
                break;
            }

        }

        String routeName;

        String stationName;


        for (HouseRoute houseRoute : houseRoutes) {
            if (houseRoute.getId().toString().equals(routeId)) {
                routeName = houseRoute.getName();
                QueryTag routeTag = new QueryTag();
                routeTag.setTagName(routeName);
                routeTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area, keyword,type,"routeId"));
                queryTags.add(routeTag);
                for (HouseRouteStation houseRouteStation : houseRoute.getStationList()) {
                    if (houseRouteStation.getId().toString().equals(stationId)) {
                        stationName = houseRouteStation.getName();

                        QueryTag stationTag = new QueryTag();
                        stationTag.setTagName(stationName);

                        stationTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area, keyword,type,"stationId"));
                        queryTags.add(stationTag);

                    }
                }
                break;
            }

        }

        String roomNumName = QueryConstants.ROOM_NUM.get(roomNum);

        if (roomNumName != null) {
            QueryTag roomNumTag = new QueryTag();
            roomNumTag.setTagName(roomNumName);
            roomNumTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area, keyword,type,"roomNum"));
            queryTags.add(roomNumTag);
        }

        String rentName = QueryConstants.RENT.get(rent);
        if (rentName != null) {
            QueryTag rentTag = new QueryTag();
            rentTag.setTagName(rentName);
            rentTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area,keyword,type, "rent"));
            queryTags.add(rentTag);
        }
        String areaName = QueryConstants.AREA.get(area);
        if (areaName != null) {
            QueryTag areaTag = new QueryTag();
            areaTag.setTagName(areaName);
            areaTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area,keyword,type, "area"));
            queryTags.add(areaTag);
        }

        if(!StringUtils.isBlank(keyword)){
            QueryTag keywordTag = new QueryTag();
            keywordTag.setTagName(keyword);
            keywordTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area,keyword,type, "keyword"));
            queryTags.add(keywordTag);
        }
        String typeName = QueryConstants.TYPE.get(type);
        if(typeName !=null){
            QueryTag typeTag = new QueryTag();
            typeTag.setTagName(typeName);
            typeTag.setCloseHref(getCloseHref(countyId, townId, routeId, stationId, roomNum, rent, area,keyword,type, "type"));
            queryTags.add(typeTag);
        }
        return queryTags;

    }


    private String getCloseHref(String countyId,
                                String townId,
                                String routeId,
                                String stationId,
                                String roomNum,
                                String rent,
                                String area
            ,String keyword, String type,String removeKey) {


        Map<String, String> map = new HashMap<>();
        map.put("countyId", countyId);
        map.put("townId", townId);
        map.put("routeId", routeId);
        map.put("stationId", stationId);
        map.put("roomNum", roomNum);
        map.put("rent", rent);
        map.put("area", area);
        map.put("keyword",keyword);
        map.put("type",type);

        map.remove(removeKey);

        StringBuilder stringBuilder = new StringBuilder();

        int i = 0;
        for (String key : map.keySet()) {

            stringBuilder.append(key).append("=").append(map.get(key));
            if (++i != map.size()) {
                stringBuilder.append("&");
            }
        }

        return stringBuilder.toString();

    }
}
